#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>


// 子线程任务函数 --- 发送信息
void * send_msg(void* arg)        
{
    // 1、将自身设置为分离属性(此线程函数结束后，自动有人给它收尸)
    pthread_detach(pthread_self());     // pthread_self函数可以获取自己的线程id

    // 2、转换参数的类型
    int *p = (int*)arg;

    // 3、正常运行的线程功能(接收来自于服务端发过来的信息)
    while (1)
    {
        // 发送信息
        char buf[1024] = {0};
        printf("请输入要发送给客户端的信息:\n");
        scanf("%s", buf);
        
        write(*p, buf, strlen(buf));
        if(strncmp(buf, "byebye", 6) == 0)
            break;
    }
}


// 主线程任务函数 --- 接收信息
int main(int argc, char const *argv[])
{
    // 1、创建TCP服务端通信对象(a、买了一部手机)
    int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (tcp_socket < 0)
    {
        perror("创建TCP服务端通信对象失败!\n");
        return -1;
    }
    
    // 使套接字sockfd关联的地址在套接字关闭后立即释放
    int on = 1;
    setsockopt(tcp_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));  //开启端口复用功能 

    // 2、绑定信息(b、填写自己的信息、并插卡)(服务端一定要填写信息)
    // struct sockaddr *addr;                             // 旧地址结构体，已经废弃掉了
    struct sockaddr_in addr;                              // 创建一个服务器地址结构体
    addr.sin_family         = AF_INET;                    // 设置地址族为IPv4
    addr.sin_port           = htons(8080);                // 设置端口号为8080
    // addr.sin_addr.s_addr = inet_addr("192.168.10.2");  // 设置IP地址为192.168.10.2
    addr.sin_addr.s_addr    = INADDR_ANY;                 // 绑定当前系统的所有IP地址

    int ret_b = bind(tcp_socket, (struct sockaddr *)&addr, sizeof(addr));
    if(ret_b < 0)
    {
        perror("绑定服务器失败\n");
        return -2;
    }
    else
    {
        printf("绑定服务器成功!\n");
    }

    // 3、监听(c、等待其他人，打电话给自己)
    int ret_l = listen(tcp_socket, 5);
    if (ret_l < 0)
    {
        perror("监听失败\n");
        return -3;
    }


    // 4、接收客户端的链接请求(d、是否接通这些人(监听的人)之中一个人的电话)
    printf("等待客户端的链接中!\n");
    int new_socket =  accept(tcp_socket, NULL, NULL);
    if (new_socket < 0)
    {
        perror("接收信息失败\n");
        return -4;
    }
    else
    {
        printf("新的客户端连接成功\n");
        // 子线程(发声孔)：
        pthread_t send_msg_ptid;
        pthread_create(&send_msg_ptid, NULL , send_msg, (void *)&new_socket);
    } 

    // 5、主线程(听筒): 读取来自客户端发送的信息(e、开始和这些人之一通话)
    while (1)
    {
        // 接收信息
        char buf[1024] = {0};
        read(new_socket, buf, sizeof(buf));    // 从txt2_fd文件描述符中，读取128个字节的数据，放到read_buf里面
        printf("从客户端收到的信息为 = %s\n", buf);

        if(strncmp(buf, "byebye", 6) == 0)
             pthread_exit(NULL);
    }

    // 6、关闭通信(f、挂掉电话)
    close(new_socket);
    close(tcp_socket);
    

    return 0;
}
